import {
  ButtonProps,
  CheckboxGroupProps,
  CheckboxProps,
  DatePickerProps,
  ElTableColumn,
  FormItemProps,
  ISelectProps,
  InputNumberProps,
  InputProps,
  RadioGroupProps,
  RateProps,
  SliderProps,
  SwitchProps,
  TimePickerDefaultProps,
  UploadProps,
  cascaderProps,
} from 'element-plus';
import { Component, ExtractPropTypes, ExtractPublicPropTypes } from 'vue';

export interface IDescriptions {
  label: string;
  prop: string;
  span?: number;
  width?: string | number;
  minWidth?: string | number;
  align?: 'left' | 'center' | 'right';
  labelAlign?: 'left' | 'center' | 'right';
  className?: string;
  labelClassName?: string;
}

export type ISearchAction = ISearchActionButton | ISearchActionDropdown | ISearchActionUpload | ISearchActionSlot;
interface ISearchActionBase {
  label: string;
  prop: string;
  option?: Partial<ButtonProps> & Record<string, any>;
}
interface ISearchActionSlot extends ISearchActionBase {
  type: 'slot';
  option?: Record<string, any>;
}
interface ISearchActionButton extends ISearchActionBase {
  type: 'button';
}
interface ISearchActionUpload extends ISearchActionBase {
  type: 'upload';
  uploadOption?: Partial<UploadProps> & Record<string, any>;
}
interface ISearchActionDropdown extends ISearchActionBase {
  type: 'dropdown';
  dropList: Array<{
    prop: string;
    label: string;
    icon?: string | Component;
    disabled?: boolean;
    divided?: boolean;
  }>;
}

export type IForm = Partial<FormItemProps> &
  Record<string, any> & { column?: number; prop: string; label: string } & (
    | { type: 'input'; option?: Partial<InputProps> & Record<string, any> }
    | { type: 'select'; selectOption?: ISelectOption; option?: Partial<ISelectProps> & Record<string, any> & ISelectApiOption }
    | { type: 'selectWithAll'; option?: Partial<ISelectProps> & Record<string, any> }
    | { type: 'switch'; option?: Partial<SwitchProps> & Record<string, any> }
    | { type: 'number'; option?: Partial<InputNumberProps> & Record<string, any> }
    | { type: 'cascader'; option?: Partial<ExtractPropTypes<typeof cascaderProps>> & Record<string, any> }
    | { type: 'treeSelect'; option?: Partial<ISelectProps> & Record<string, any> & ISelectApiTreeOption }
    | { type: 'datePicker'; option?: Partial<DatePickerProps> & Record<string, any> }
    | { type: 'timePicker'; option?: Partial<TimePickerDefaultProps> & Record<string, any> }
    | { type: 'timeSelect'; option?: Record<string, any> }
    | { type: 'radioGroup'; selectOption?: ISelectOption; option?: Partial<RadioGroupProps> & Record<string, any> }
    | { type: 'rate'; option?: Partial<RateProps> & Record<string, any> }
    | { type: 'slider'; option?: Partial<SliderProps> & Record<string, any> }
    | { type: 'checkbox'; option?: Partial<CheckboxProps> & Record<string, any> }
    | { type: 'checkboxGroup'; selectOption?: ISelectOption; option?: Partial<CheckboxGroupProps> & Record<string, any> }
    | { type: 'upload'; option?: Partial<UploadProps> & Record<string, any> }
    | { type: 'singleUpload'; option?: Partial<InputProps> & Record<string, any>; uploadOption?: Partial<UploadProps> & Record<string, any> }
    | { type: 'text'; option?: { textRender?: (data: any) => any } & Record<string, any> }
    | { type: 'slot'; option?: Record<string, any> }
  );

interface ISelectApiFormatterFn {
  label: string;
  value: string;
  children?: { label: string; value: string }[];
}

interface ISelectApiTreeOption {
  api?: () => Promise<any>;
  formatterFn?: (data: any) => { label: string; value: string; children?: ISelectApiFormatterFn[] }[];
}
export interface ISelectOption {
  label?: string;
  value?: string;
  options: Array<{ label?: any; value?: any; disabled?: boolean } & Record<string, any>>;
}
export interface ISelectApiOption {
  api?: () => Promise<any>;
  formatterFn?: (data: any) => { label: string; value: string }[];
}

export interface IPageInfo {
  pageSize: number;
  page: number;
}

export interface ITableAction {
  label: string;
  prop: string;
  type?: '' | 'default' | 'text' | 'success' | 'warning' | 'info' | 'primary' | 'danger';
  icon?: string | Component;
  option?: Partial<ButtonProps> & { customDisabled?: (row: any) => any } & Record<string, any>;
}
export interface ITableMenu {
  label: string;
  prop: string;
  icon: string | Component;
}

type TableColumnProps = ExtractPublicPropTypes<InstanceType<typeof ElTableColumn>['$props']>;
export interface ITableColumn extends TableColumnProps {
  label: string;
  prop: string;
  hideColumu?: boolean;
  childHead?: ITableColumn[];
}
